package edu.ustb.mis.dm.impl.data;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import edu.ustb.mis.dm.Constants;
import edu.ustb.mis.dm.interfaces.data.DataPrepare;
import edu.ustb.mis.dm.model.unit.impl.Instance;
import edu.ustb.mis.dm.util.Utils;

/**
 * 文本形式输入数据准备的实现，属性间以"，"隔开
 * 
 * @author Saya
 */
public class TextInputDataPrepare implements DataPrepare<Instance> {
	private static final Random random = new Random();

	private List<Instance> instanceList = new ArrayList<Instance>();

	private final String inputPath;

	private final String outputPath;

	public TextInputDataPrepare(final String data_set_name) {
		this.inputPath = new StringBuffer(Constants.INPUT_PREFIX).append(data_set_name).append(Constants.TXT_SUFFIX).toString();
		this.outputPath = new StringBuffer("output/").append(data_set_name).append(Constants.DATA_SUFFIX).toString();
	}

	/**
	 * 由一个符合格式的字符串组装一个Instance实例
	 * 
	 * @param instanceString
	 * @return
	 */
	private Instance buildInstance(final String instanceString) {
		String classID;
		int size;
		final String[] tArray = Utils.split(instanceString, ',');
		final BitSet bitSet = new BitSet();
		classID = tArray[0];
		size = tArray.length;
		final Set<Integer> attSet = new HashSet<Integer>();
		for (int i = 1; i < size; i++) {
			//if (tArray[i].equals("?")) {
			//} else {
				bitSet.set(Integer.parseInt(tArray[i]));
				attSet.add(Integer.parseInt(tArray[i]));
			//}
		}
		return new Instance(classID, bitSet, attSet);
	}

	public String getInputPath() {
		return inputPath;
	}

	public List<Instance> getInstanceList() {
		return instanceList;
	}

	public String getOutputPath() {
		return outputPath;
	}

	/**
	 * 初始化数据，实现DataPrepare接口方法，由以","隔开的文本得到Instance类型的List
	 */
	public List<Instance> initData() {
		final File file = new File(outputPath);
		if (file.exists()) {
			instanceList = Utils.deserialization(file);
		} else {
			try {
				final Reader reader = new BufferedReader(new FileReader(inputPath));
				String instanceString = Utils.readLine(reader);
				while (instanceString != null) {
					instanceList.add(buildInstance(instanceString));
					instanceString = Utils.readLine(reader);
				}
				reader.close();
				Utils.serialization(instanceList, outputPath);
			} catch (final IOException e) {
				e.printStackTrace();
			}
		}
		Collections.shuffle(instanceList, random);
		return instanceList;
	}
}
